Moderate Denoising

Modified Files:

src/render.cpp (for generating variance map>

src/main.cpp

scenes/denoising/python/moderate denoising (independent variance estimate) (python code, for denoising)

Validation Files:

image without noise: scenes/denoising/cbox/cbox_path_mats_16384.exr

image with noise: scenes/denoising/cbox/cbox_path_mats_512.exr

image variance: scenes/denoising/cbox/cbox_path_mats_512_var_var.exr

denoised image: scenes/denoising/python/denoised_xxx.exr

Implementation

Our implementation follows the patchwise implementation algorithm of Non-Local Means Denoising and the pesudo code introduced in the course slide.

Instead of generating one pixel's value completely then going to the other pixel, the fast implementation at each time only considers the contributions of patches pairs with same offsets. The first average convolution compute the difference map between two pacthes centered around the pixel. Since the contribution is patch-wise, a pixel could be contributed by multiple same-offset patch pairs as long as it's within the patch scope. This contribution is computed by the second average convolution on the difference map. The final value for each pixel is the weighted sum divided by weights.

The original paper uses the uniform variance for all pixels, we improve this by estimating pixel-wise variance during the rendering. The sample mean variance estimate algorithm is Welford's online algorithm, which is introduced in the course slides. To achieve this, auxillary data structures storing one sample for each image pixel, mean, mean2 are created.

Implementation Details:

1. denoising is performed on Python, image and image variance are stored as numpy array and convolution operator is from scipy.

2. for image boundary handling, I tried wrap(circular), mirror and nearest padding method. The results produced have negligible differences (only visible by tev comparing mode).

3. scipy.signal.convolve() and scipy.ndimage.convolve() both provides convolution operations. The difference is that the former has much higher efficiency but supports only 2D conv and limited padding, the latter supprots diverse padding and nD conv but the efficiency is low. I implemented both versions.

4. EXR file reading and writing requires opencv, OpenEXR, Imath packages.

5. The render doesn't export mean variance image by default, to enable the function, ./nori xxx.xml require_varmap true

Validation

Noisy Image and Variance

The noisy image is generated by 512 sampling with MATS integrator. To verify the correctness of the rendered image and its corresponding pixel mean variance image, I visualize them on the jupyter notebook. The original image is transformed by gamma function for visualization, the mean variance image is x512 for visualization.

noisy image (gamma) mean variance (x512)

ingredients for denoising


Comparison: noisy, denoised, noise-free

The noise-free image is generated by 16384 samples with MATS integrator. The padding mode for the selected denoised image is 'wrap'(a.k.a circular) because it have the best efficiency. The parameters r, f, k for denoising are 10, 3, 0.45 respectively.

noisy (512) denoised noise free (16384)

Comparison Between Denoised and Noise-Free Images


Comparison: different boundary padding modes

By tev pixel-wise comparsion, the denoised images are almost same under different padding modes and have no visual differences.

original wrap denoised mirror denoised nearest denoised

Comparison on different padding modes


.center { display: block; margin-left: auto; margin-right: auto; width: 50%; }